-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustdoc: clean up generic impls #52827
Conversation
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
cc @eddyb |
src/librustdoc/clean/blanket_impl.rs
Outdated
use self::finder_trait::Finder; | ||
|
||
pub struct BlanketImplFinder<'a, 'tcx: 'a, 'rcx: 'a> { | ||
pub cx: &'a core::DocContext<'a, 'tcx, 'rcx>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just add methods to DocContext
? Also, I'd rename the methods so they all start with get_blanket_impls_for_...
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Moving into DocContext
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it's weird to move it directly into DocContext
... Why would the DocContext
provide for blanket impls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's the global object of rustdoc and this is part of what rustdoc needs to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whenever this PR is merged, i'd like to move the auto/blanket impl collection (as well as all the other explicit impl collection) into an early pass, so the code can be isolated over there instead.
src/librustdoc/clean/def_ctor.rs
Outdated
def_id: DefId, | ||
callback: &F, | ||
) -> Vec<Item> | ||
where F: Fn(& dyn Fn(DefId) -> Def) -> Vec<Item> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do this generally by replacing Vec<Item>
with R
. Also you can get the DefId
from TyAdt
, so why not just return an Option<Def>
, with no callback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filtering is done before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why would it be better to replace Vec<Item>
with R
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because Vec<Item>
is very arbitrary and the function doesn't have anything to do with Vec<Item>
, that's just what the closures it's used with deal with.
Returning Option<Def>
is probably a better idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is still outstanding, but has been hidden by future commits editing the area around it.
I would prefer to see a generic return value - that's how these callback methods tend to work. However, since there is that arm returning Vec::new()
, we should either depend on the return value implementing Default
, or restructure it so that a callback is not necessary.
src/librustdoc/clean/def_ctor.rs
Outdated
|
||
use super::*; | ||
|
||
pub fn get_def_ctor_from_def_id<F>(cx: &DocContext, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have a name like get_def_from_ty
. I'm guessing this is mostly for aliases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly yes.
src/librustdoc/clean/finder_trait.rs
Outdated
// Instead, we construct 'fake' def ids, which start immediately after the last DefId in | ||
// DefIndexAddressSpace::Low. In the Debug impl for clean::Item, we explicitly check for fake | ||
// def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds | ||
fn next_def_id(&self, crate_num: CrateNum) -> DefId { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you need new DefId
s?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid them getting filtered out because of duplicates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah hold on, it's required for the auto traits (sync and send) but not be for blanket impls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it's required for blanket impls as well otherwise they're counted as duplicates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should change the deduplication logic instead, then!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep but nothing to do with this PR. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every clean::Item
needs a DefId
. As the synthetic impls for auto
traits (and hopefully eventually, blanket traits too) invent an impl out of thin air, one needs to be created so that the Item
can hold it.
The real question is whether we can get away with only creating clean::Impl
structs, and ignoring/inferring the fields on Item
, like its attributes, visibility, stability, or deprecation. These can probably be inferred from the trait itself (or the blanket impl being applied), so that would help to prevent us from requiring new DefId
s.
0486913
to
26b387a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for refactoring this! I have a couple comments.
src/librustdoc/clean/finder_trait.rs
Outdated
use super::*; | ||
|
||
pub trait Finder<'a, 'tcx: 'a, 'rcx: 'a> { | ||
fn get_cx(&self) -> &DocContext<'a, 'tcx, 'rcx>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering why these methods need to exist on a trait like this, if all the implementor needs to do is supply a DocContext
. Could we instead add them to DocContext
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, it's just to be able to implement some methods directly inside the trait (and therefore avoid code duplication).
I like to keep things grouped by functionalities. Also, AutoTraitFinder
requires an additional field to work so I think merging it inside DocContext
would be a mistake. Therefore, I think keeping the BlanketImplFinder
struct on its own would be better. However, if you prefer me to merge it inside DocContext
, I'll.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(To pull the conversation out of discord...)
I'm not talking about AutoTraitFinder
or BlanketImplFinder
. Those are distinct enough to be on their own. I'm thinking more about just the provided methods on the Finder
trait itself.
// we need to reexport something from libstd so that `all_trait_implementations` is called. | ||
pub use std::string::String; | ||
|
||
include!("primitive/primitive-generic-impl.rs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you use include!()
here? Did it affect the result of this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replicated how it was performed in libstd. Since it's the main target of this fix, I thought it was the best way.
src/librustdoc/clean/finder_trait.rs
Outdated
// Instead, we construct 'fake' def ids, which start immediately after the last DefId in | ||
// DefIndexAddressSpace::Low. In the Debug impl for clean::Item, we explicitly check for fake | ||
// def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds | ||
fn next_def_id(&self, crate_num: CrateNum) -> DefId { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every clean::Item
needs a DefId
. As the synthetic impls for auto
traits (and hopefully eventually, blanket traits too) invent an impl out of thin air, one needs to be created so that the Item
can hold it.
The real question is whether we can get away with only creating clean::Impl
structs, and ignoring/inferring the fields on Item
, like its attributes, visibility, stability, or deprecation. These can probably be inferred from the trait itself (or the blanket impl being applied), so that would help to prevent us from requiring new DefId
s.
b006fc2
to
d57f3a6
Compare
Outstanding comments:
Otherwise, this looks ready to go! If we can get this landed, we can build farther refactors on top of it. @bors r+ |
📌 Commit d57f3a6 has been approved by |
rustdoc: clean up generic impls r? @QuietMisdreavus
☀️ Test successful - status-appveyor, status-travis |
r? @QuietMisdreavus